namespace DA.AnimGraph {

    internal unsafe struct Slot {
        SlotNode* node;
        public int curPortId;
        public int graphIndexInPort0;
        public int graphIndexInPort1;
        public Slot(SlotNode* node) {
            this.node = node;
            graphIndexInPort0 = -1;
            graphIndexInPort1 = -1;
            curPortId = -1;
        }

        /// <summary>
        /// 将 graph 连接到 SlotNode
        /// </summary>
        /// <returns>
        /// 被顶替掉的，原此 slot 连接的 graph 序号，若之前没有其它 graph 则为 -1。
        /// 若已经连接到此slot，返回-2
        /// </returns>
        public int Connect(in AnimGraph* graph) {
            var newIndex = graph->graphArrayInfo.indexInArray;
            if (newIndex == graphIndexInPort0) {
                curPortId = 0;
                node->ReEnter(0);
                return -2;
            } else if (newIndex == graphIndexInPort1) {
                curPortId = 1;
                node->ReEnter(1);
                return -2;
            }

            int portId = node->Connect(graph->rootNode);
            curPortId = portId;
            int oldGraphIndex = GetGraphId(portId);
            SetGraphId(portId, graph->graphArrayInfo.indexInArray);

            // 给 SlotNode 设置 GraphContext
            var graphContext = graph->GetGraphContext();
            node->SetChildrenContext(portId, graphContext);

            return oldGraphIndex;
        }

        public void Disconnect(in AnimGraph* graph) {
            var index = graph->graphArrayInfo.indexInArray;
            if (index == graphIndexInPort0) {
                node->Disconnect(0);
            } else if (index == graphIndexInPort1) {
                node->Disconnect(1);
            }
        }

        internal void SetGraphContextToSlot(int graphIndex, in GraphContext* graphContext) {
            int port = GetPortByGraphIndex(graphIndex);
            if (port >= 0) {
                node->SetChildrenContext(port, graphContext);
            }
        }

        void SetGraphId(int portIndex, int value) {
            if (portIndex == 0) {
                graphIndexInPort0 = value;
            } else {
                graphIndexInPort1 = value;
            }
        }
        int GetGraphId(int portIndex) {
            if (portIndex == 0) {
                return graphIndexInPort0;
            } else {
                return graphIndexInPort1;
            }
        }

        int GetPortByGraphIndex(int graphIndex) {
            if (graphIndex == graphIndexInPort0) return 0;
            if (graphIndex == graphIndexInPort1) return 1;
            return -1;
        }
    }
}
